import pandas as pd
import numpy as np
from datetime import datetime
from sklearn.preprocessing import StandardScaler

# 1. 数据预处理
# 读取数据（假设数据为CSV格式）
user_info = pd.read_csv('user_info_format1.csv')
user_log = pd.read_csv('user_log_format1.csv')

# 用户属性缺失值处理
user_info['gender'] = user_info['gender'].fillna(2)  # 缺失值用2替换
user_info['gender'] = user_info['gender'].replace({2: 'unknown'})  # 将2转换为unknown
user_info['age_range'] = user_info['age_range'].fillna(0)  # 缺失值用0替换

# 映射年龄范围
age_mapping = {
    1: '<18',
    2: '18-24',
    3: '25-29',
    4: '30-34',
    5: '35-39',
    6: '40-49',
    7: '≥50',
    8: '≥50',
    0: 'unknown'
}
user_info['age_range'] = user_info['age_range'].map(age_mapping)

# 用户行为数据缺失值处理
user_log['brand_id'] = user_log['brand_id'].fillna(0)  # brand_id缺失值用0替换

# 处理时间戳：转换为标准日期格式（假设年份为当前年）
current_year = datetime.now().year
user_log['date'] = pd.to_datetime(user_log['time_stamp'].apply(lambda x: f"{current_year}{int(x):04d}"),
                                  format='%Y%m%d',
                                  errors='coerce')

# 删除无效日期记录
user_log = user_log.dropna(subset=['date'])

# 处理其他缺失值
user_log = user_log.dropna(subset=['user_id', 'seller_id', 'action_type'])
user_info = user_info.dropna(subset=['user_id'])

# 合并数据
merged_data = pd.merge(user_log, user_info, on='user_id', how='left')

# 2. 特征工程
# 辅助列：标记不同行为类型
merged_data['is_buy'] = (merged_data['action_type'] == 2).astype(int)
merged_data['is_click'] = (merged_data['action_type'] == 0).astype(int)
merged_data['is_add'] = (merged_data['action_type'] == 1).astype(int)
merged_data['is_collect'] = (merged_data['action_type'] == 3).astype(int)

# --------------------- 用户级特征 ---------------------
# 用户总交互次数
user_action_num = merged_data.groupby('user_id').size().reset_index(name='u_action_num')

# 用户购买次数
user_buy_num = merged_data[merged_data['is_buy'] == 1].groupby('user_id')['is_buy'].count().reset_index(name='buy_count')

# 计算用户购买率
user_features = pd.merge(user_action_num, user_buy_num, on='user_id', how='left')
user_features['u_buy_rate'] = user_features['buy_count'] / user_features['u_action_num']

# 用户购买时间间隔
buy_events = merged_data[merged_data['is_buy'] == 1].copy()
buy_events = buy_events.sort_values(['user_id', 'date'])
buy_events['prev_buy_date'] = buy_events.groupby('user_id')['date'].shift()
buy_events['buy_interval'] = (buy_events['date'] - buy_events['prev_buy_date']).dt.days

# 平均购买间隔
user_buy_interval = buy_events.groupby('user_id')['buy_interval'].mean().reset_index(name='u_buy_time')
user_features = pd.merge(user_features, user_buy_interval, on='user_id', how='left')

# 处理NaN值
user_features['u_buy_rate'] = user_features['u_buy_rate'].fillna(0)
user_features['u_buy_time'] = user_features['u_buy_time'].fillna(0)

# --------------------- 商家级特征 ---------------------
# 商家被交互次数
merchant_action_num = merged_data.groupby('seller_id').size().reset_index(name='m_action_num')

# 与商家交互的用户数
merchant_action_u = merged_data.groupby('seller_id')['user_id'].nunique().reset_index(name='m_action_u')

# 商家各类行为次数
merchant_actions = merged_data.groupby('seller_id').agg(
    m_buy=('is_buy', 'sum'),
    m_click=('is_click', 'sum'),
    m_add=('is_add', 'sum'),
    m_collect=('is_collect', 'sum')
).reset_index()

# 商家购买率
merchant_features = pd.merge(merchant_action_num, merchant_action_u, on='seller_id')
merchant_features = pd.merge(merchant_features, merchant_actions, on='seller_id')
merchant_features['m_buy_rate'] = merchant_features['m_buy'] / merchant_features['m_action_num']

# 商家复购次数
# 复购定义：同一用户对同一商家购买次数>1
rebuy_data = merged_data[merged_data['is_buy'] == 1]
user_merchant_buys = rebuy_data.groupby(['user_id', 'seller_id']).size().reset_index(name='buy_times')
user_merchant_buys['rebuy_times'] = user_merchant_buys['buy_times'] - 1
merchant_rebuy = user_merchant_buys[user_merchant_buys['rebuy_times'] > 0].groupby('seller_id')['rebuy_times'].sum().reset_index(name='m_rebuy')
merchant_features = pd.merge(merchant_features, merchant_rebuy, on='seller_id', how='left').fillna(0)

# 商家购买时间间隔
merchant_buy_events = rebuy_data.sort_values(['seller_id', 'date'])
merchant_buy_events['prev_buy_date'] = merchant_buy_events.groupby('seller_id')['date'].shift()
merchant_buy_events['buy_interval'] = (merchant_buy_events['date'] - merchant_buy_events['prev_buy_date']).dt.days
merchant_buy_interval = merchant_buy_events.groupby('seller_id')['buy_interval'].mean().reset_index(name='m_buy_time')
merchant_features = pd.merge(merchant_features, merchant_buy_interval, on='seller_id', how='left').fillna(0)

# --------------------- 用户-商家级特征 ---------------------
# 用户对商家的行为统计
user_merchant_features = merged_data.groupby(['user_id', 'seller_id']).agg(
    u_m_click=('is_click', 'sum'),
    u_m_add=('is_add', 'sum'),
    u_m_buy=('is_buy', 'sum'),
    u_m_collect=('is_collect', 'sum')
).reset_index()

# 用户对商家的购买率
user_merchant_features['total_interactions'] = user_merchant_features[['u_m_click', 'u_m_add', 'u_m_buy', 'u_m_collect']].sum(axis=1)
user_merchant_features['u_m_buy_rate'] = user_merchant_features['u_m_buy'] / user_merchant_features['total_interactions']

# 同一时间用户对商家的购买率
# 先计算每个商家在每个时间点的购买率
time_merchant_buy_rate = merged_data.groupby(['seller_id', 'date']).agg(
    time_buy=('is_buy', 'sum'),
    time_total=('action_type', 'count')
).reset_index()
time_merchant_buy_rate['time_buy_rate'] = time_merchant_buy_rate['time_buy'] / time_merchant_buy_rate['time_total']

# 合并到原始数据
user_merchant_time = pd.merge(
    merged_data[['user_id', 'seller_id', 'date']],
    time_merchant_buy_rate[['seller_id', 'date', 'time_buy_rate']],
    on=['seller_id', 'date'],
    how='left'
)

# 计算用户-商家平均时间购买率
time_u_m_buy_rate = user_merchant_time.groupby(['user_id', 'seller_id'])['time_buy_rate'].mean().reset_index(name='time_u_m_buy_rate')

# 合并所有用户-商家特征
user_merchant_features = pd.merge(
    user_merchant_features,
    time_u_m_buy_rate,
    on=['user_id', 'seller_id'],
    how='left'
).fillna(0)

# --------------------- 合并所有特征 ---------------------
# 创建基础表（所有用户-商家组合）
all_combinations = merged_data[['user_id', 'seller_id']].drop_duplicates()

# 合并用户特征
final_features = pd.merge(all_combinations, user_features, on='user_id', how='left')

# 合并商家特征
final_features = pd.merge(final_features, merchant_features, on='seller_id', how='left')

# 合并用户-商家特征
final_features = pd.merge(
    final_features,
    user_merchant_features,
    on=['user_id', 'seller_id'],
    how='left'
)

# 填充可能的NaN值
final_features = final_features.fillna(0)

# 删除中间辅助列
final_features = final_features.drop(columns=['buy_count', 'total_interactions'])

# 3. 数据标准化
# 选择需要标准化的数值型特征列
numeric_features = [
    'u_action_num', 'u_buy_time',
    'm_action_num', 'm_action_u', 'm_buy', 'm_click', 'm_collect', 'm_add', 'm_rebuy', 'm_buy_time',
    'u_m_click', 'u_m_add', 'u_m_buy', 'u_m_collect'
]

# 选择比率型特征（不标准化）
ratio_features = [
    'u_buy_rate', 'm_buy_rate', 'u_m_buy_rate', 'time_u_m_buy_rate'
]

# 创建标准化器
scaler = StandardScaler()

# 对数值型特征进行标准化
scaled_features = scaler.fit_transform(final_features[numeric_features])
scaled_df = pd.DataFrame(scaled_features, columns=[f"{col}" for col in numeric_features])

# 合并标准化后的特征回原DataFrame
final_features_scaled = pd.concat([final_features[['user_id', 'seller_id']],
                                  scaled_df,
                                  final_features[ratio_features]], axis=1)

# 4. 保存结果
final_features_scaled.to_csv('final_features_scaled.csv', index=False)

print("特征工程和标准化完成！")
print("标准化后的特征数:", len(final_features_scaled.columns) - 2)
print("特征列表:", final_features_scaled.columns.tolist())